package com.pzsh.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.pzsh.constant.EOLINKERConstants;
import com.pzsh.constant.ThreadPoolsConstants;
import com.pzsh.entity.*;
import com.pzsh.entity.vo.OrderVo;
import com.pzsh.enums.ErrorCodeEnum;
import com.pzsh.exception.ApiException;
import com.pzsh.jwt.ITokenManager;
import com.pzsh.mapper.*;
import com.pzsh.redis.IRedisService;
import com.pzsh.service.IOrderService;
import com.pzsh.sms.sanwang.util.HttpUtils;
import com.pzsh.util.BigDecimalUtil;
import com.pzsh.util.PageResult;
import com.pzsh.util.RowBoundUtil;
import com.pzsh.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMethod;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description:
 * @Param:
 * @return:
 * @Author: GXL
 * @Date: 2019/12/09
 */
@Slf4j
@Service
@Transactional(propagation = Propagation.SUPPORTS)
public class OrderServiceImpl implements IOrderService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IRedisService redisService;

    @Autowired
    private ITokenManager tokenManager;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private TransactionssMapper transactionssMapper;

    @Autowired
    private RewardTaskMapper rewardTaskMapper;

    @Autowired
    private CensusMapper censusMapper;

    @Autowired
    private SpecialMapper specialMapper;

    @Autowired
    private SpendMoneyMapper spendMoneyMapper;

    @Autowired
    private UserPackMapper userPackMapper;

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public PageResult<List<OrderVo>> getOrdersByUserId(String account, Integer status, Integer pageSize, Integer rowSize) {
        UserEntity entity = new UserEntity();
        entity.setAccount(account);
        entity = userMapper.selectOne(entity);

//        OrderEntity orderEntity = new OrderEntity();
//        orderEntity.setUserId(entity.getUserId());
//        if (!status.equals(5)){
//            orderEntity.setStatus(status);
//        }
//        RowBounds rowBounds = new RowBounds((pageSize - 1) * rowSize, rowSize);
//        List<OrderEntity> list = orderMapper.selectByRowBounds(orderEntity,rowBounds);

        PageResult list=new PageResult();
        Example example=new Example(OrderEntity.class);
        example.setOrderByClause("order_id desc");
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", entity.getUserId());
        if(status!=null && !status.equals(5))
            criteria.andEqualTo("status", status);

        RowBounds rowBounds = RowBoundUtil.getRowBounds(rowSize, pageSize);
        List<OrderEntity> orderEntities = orderMapper.selectByExampleAndRowBounds(example, rowBounds);

        List<OrderVo> orderVos = new ArrayList<>();
        for (OrderEntity obj : orderEntities) {
            OrderVo  orderVo = new OrderVo();
            orderVo.setOrderId(obj.getOrderId());
            orderVo.setSerialNum(obj.getSerialNum());
            orderVo.setUserId(obj.getUserId());
            orderVo.setGoodsName(obj.getGoodsName());
            orderVo.setNumb(obj.getNumb());
            orderVo.setMainPicture(obj.getMainPicture());
            orderVo.setPrice(BigDecimalUtil.caseString_2(obj.getPrice()));
            orderVo.setTotalPrice(BigDecimalUtil.caseString_2(obj.getTotalPrice()));
            orderVo.setDisPrice(BigDecimalUtil.caseString_2(obj.getDisPrice()));
            orderVo.setGivePs(obj.getGivePs()==null ? null : BigDecimalUtil.caseString_2(obj.getGivePs()));
            orderVo.setRewardPs(obj.getRewardPs()==null ? null : BigDecimalUtil.caseString_2(obj.getRewardPs()));
            orderVo.setGid(obj.getGid());
            orderVo.setStatus(obj.getStatus());
            orderVo.setConsignee(obj.getConsignee());
            orderVo.setConsigneeMobile(obj.getConsigneeMobile());
            orderVo.setAddress(obj.getAddress());
            orderVo.setLogisticsCompany(obj.getLogisticsCompany());
            orderVo.setLogisticsNum(obj.getLogisticsNum());
            orderVos.add(orderVo);
        }
        list.setData(orderVos);
        list.setTotal(orderMapper.selectCountByExample(example));
        return list;
    }
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public OrderVo getOrderInfo(String account, Integer orderId) {
        UserEntity entity = new UserEntity();
        entity.setAccount(account);
        entity = userMapper.selectOne(entity);

        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setUserId(entity.getUserId());
        orderEntity.setOrderId(orderId);
        orderEntity = orderMapper.selectOne(orderEntity);

        OrderVo orderVo = new OrderVo();
        orderVo.setAddress(orderEntity.getAddress());
        orderVo.setConsigneeMobile(orderEntity.getConsigneeMobile());
        orderVo.setConsignee(orderEntity.getConsignee());
        orderVo.setCityProv(orderEntity.getCityProv());
        orderVo.setOrderId(orderEntity.getOrderId());
        orderVo.setStatus(orderEntity.getStatus());
        orderVo.setRewardPs(BigDecimalUtil.caseString_2(orderEntity.getRewardPs()==null?0:orderEntity.getRewardPs()));
        orderVo.setGivePs(BigDecimalUtil.caseString_2(orderEntity.getGivePs()==null?0:orderEntity.getGivePs()));
        orderVo.setDisPrice(BigDecimalUtil.caseString_2(orderEntity.getDisPrice()));
        orderVo.setTotalPrice(BigDecimalUtil.caseString_2(orderEntity.getTotalPrice()));
        orderVo.setPrice(BigDecimalUtil.caseString_2(orderEntity.getPrice()));
        orderVo.setMainPicture(orderEntity.getMainPicture());
        orderVo.setNumb(orderEntity.getNumb());
        orderVo.setGoodsName(orderEntity.getGoodsName());
        orderVo.setUserId(orderEntity.getUserId());
        orderVo.setSerialNum(orderEntity.getSerialNum());
        orderVo.setCityProvId(orderEntity.getCityProvId());
        orderVo.setCreateDate(orderEntity.getCreateDate());
        orderVo.setModifyDate(orderEntity.getModifyDate());
        orderVo.setLogisticsCompany(orderEntity.getLogisticsCompany());
        orderVo.setLogisticsNum(orderEntity.getLogisticsNum());

        return orderVo;
    }
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public void confirmReceive(String account, Integer orderId) {
        UserEntity userEntity = new UserEntity();
        userEntity.setAccount(account);
        userEntity = userMapper.selectOne(userEntity);

        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderId(orderId);
        orderEntity = orderMapper.selectOne(orderEntity);

        //用户赠送积分更新
//        UserPackEntity userPackEntity = new UserPackEntity();
//        userPackEntity.setUserId(userEntity.getUserId());
//        userPackEntity = userPackMapper.selectOne(userPackEntity);

        Integer totalFee = orderEntity.getTotalPrice();
        Integer totalReward = orderEntity.getRewardPs();

//        Integer integral = userPackEntity.getRewardIntegral() - totalFee;
        //按自由ps扣减比例，计算应该赠送的ps数量
//        BigDecimal D1 = new BigDecimal(Math.abs(integral));
//        BigDecimal D2 = new BigDecimal(totalFee);
//        BigDecimal D3 = D1.divide(D2,2, RoundingMode.HALF_UP);
//        BigDecimal D4 = new BigDecimal(totalReward);
//        BigDecimal D5 = D4.multiply(D3);
//        totalReward = D5.intValue();

        //奖励直推上级PS
        SpecialEntity specialEntity = new SpecialEntity();
        specialEntity.setSpKey("rewardPs");
        specialEntity = specialMapper.selectOne(specialEntity);
        BigDecimal bigDecimal = new BigDecimal(specialEntity.getSpValue());
        BigDecimal oneh = new BigDecimal(100);
        BigDecimal B1 = bigDecimal.divide(oneh,2,RoundingMode.HALF_UP);
        BigDecimal B2 = new BigDecimal(totalReward);
        BigDecimal B3 = B2.multiply(B1);
        Integer rp = B3.intValue();

        UserEntity visiuser = new UserEntity();
        visiuser.setAccount(userEntity.getVisitAccount());
        visiuser = userMapper.selectOne(visiuser);
        UserPackEntity superUser = new UserPackEntity();
        superUser.setUserId(visiuser.getUserId());
        superUser = userPackMapper.selectOne(superUser);
        superUser.setFreeIntegral(superUser.getFreeIntegral() + rp);
        userPackMapper.updateByPrimaryKey(superUser);

        //添加上级奖励财务记录
        TransactionEntity intran = new TransactionEntity();
        intran.setNumb(rp);
        intran.setRemark("下级购买商城订单奖励直推上级PS");
        intran.setTType(18);
        intran.setCreateDate(new Timestamp(new Date().getTime()));
        intran.setModifyDate(new Timestamp(new Date().getTime()));
        intran.setRecordType(0);
        intran.setInoutType(1);
        intran.setUserId(visiuser.getUserId());
        intran.setAccount(visiuser.getAccount());
        transactionssMapper.insert(intran);

//        userPackMapper.updateByPrimaryKey(userPackEntity);

        //**累计普通商品总消费ps
        CensusEntity censusEntity = censusMapper.selectAll().get(0);
        censusEntity.setCountGoodsOrder(censusEntity.getCountGoodsOrder() + 1);
        censusEntity.setCountGoodsBuy(censusEntity.getCountGoodsBuy() + totalFee);
        censusEntity.setCountRewardPs(censusEntity.getCountRewardPs() + totalReward);
        censusMapper.updateByPrimaryKey(censusEntity);

        //请求RD积分系统接口--创建订单
        Map<String, String> headers = new HashMap<String, String>();
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        bodys.put("no", orderEntity.getSerialNum());
        bodys.put("username", userEntity.getAccount());
        Double disPrice = Double.valueOf(totalFee / 100);
        bodys.put("money", disPrice.toString());
        bodys.put("type", "0");//普通商品传 0
        bodys.put("wallet", "1");
        try {
            HttpResponse response = HttpUtils.doPost(EOLINKERConstants.DOMAIN_URL,EOLINKERConstants.ORDER_ADD, RequestMethod.POST.name(),headers,querys,bodys);
            String str = EntityUtils.toString(response.getEntity());
            JSONObject jsonObject = JSONObject.parseObject(str);
            log.info("RD系统返回-创建订单(普通商品)：{}",jsonObject.toJSONString());
            Integer status = jsonObject.getInteger("status");
            if (!status.equals(0)){
                throw new ApiException(ErrorCodeEnum.PARAM_200014.code(),String.format(ErrorCodeEnum.PARAM_200014.msg(),"创建订单(普通商品)"));
            }
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            throw new ApiException(ErrorCodeEnum.PARAM_200014.code(),String.format(ErrorCodeEnum.PARAM_200014.msg(),"创建订单(普通商品)"));
        }

        //奖励积分
        if (orderEntity.getRewardPs() != null && !"0".equals(orderEntity.getRewardPs())){
            final Integer rewardPs = totalReward; //奖励积分，30天后，分returnDays天奖励用户
            final Integer returnDay = orderEntity.getReturnDays();
            final Integer rewardUser = userEntity.getUserId();
            final String seriaNum = orderEntity.getSerialNum();
            ThreadPoolsConstants.rewardThreadPool.execute(new Runnable(){
                @Override
                public void run() {
                    Integer rewardIntegral = rewardPs;
                    Integer returnDays = returnDay;

                    Integer rateDays = 30;//30天后开始返还
                    Integer s = rewardIntegral % returnDays;//取模，此数量最后一天一起奖励用户，结束
                    rewardIntegral = (rewardIntegral - s) / returnDays; //平均每天奖励多少ps
                    s = rewardIntegral + s; //最后一天奖励

                    int lastday = rateDays + returnDays;
                    int today = rateDays;
                    while (today < lastday){
                        today = today + 1;
                        Timestamp rewardDate = new Timestamp(new Date().getTime() + today*24*60*60*1000L);
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
                        Long rewardDateForFind = Long.valueOf(dateFormat.format(rewardDate.getTime()));

                        RewardTaskEntity rewardTaskEntity = new RewardTaskEntity();
                        rewardTaskEntity.setStatus(0);
                        rewardTaskEntity.setUserId(rewardUser);
                        rewardTaskEntity.setSeriaNum(seriaNum);
                        rewardTaskEntity.setRewardDate(rewardDate);
                        rewardTaskEntity.setRewardDateForFInd(rewardDateForFind);
                        rewardTaskEntity.setRewardPs(rewardIntegral);
                        if (today == lastday){//若是最后一天，则奖励剩余的ps
                            rewardTaskEntity.setRewardPs(s);
                        }
                        rewardTaskMapper.insert(rewardTaskEntity);
                    }
                }
            });
        }

        //更新订单状态
        orderEntity = orderMapper.selectOne(orderEntity);
        orderEntity.setStatus(3);
        orderMapper.updateByPrimaryKey(orderEntity);

        //更新累计消费
        UserSpendEntity userSpendEntity = new UserSpendEntity();
        userSpendEntity.setUserId(userEntity.getUserId());
        userSpendEntity = spendMoneyMapper.selectOne(userSpendEntity);
        userSpendEntity.setSpendMoneyGoods(userSpendEntity.getSpendMoneyGoods() + orderEntity.getDisPrice());
        userSpendEntity.setSpendMoney(userSpendEntity.getSpendMoney() + orderEntity.getDisPrice());
        spendMoneyMapper.updateByPrimaryKey(userSpendEntity);

        //升级用户 --> vip
//        if (userSpendEntity.getSpendMoneyGoods() >= 1200 && entity.getGrade()==-1){
//            entity.setGrade(0);
//            userMapper.updateByPrimaryKey(entity);
//        }

    }
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public PageResult<List<OrderEntity>> selectByRowBounds(String account, Integer status, Integer gtype, Integer pageSize, Integer rows) {

        PageResult list=new PageResult();
        Example example=new Example(OrderEntity.class);
        example.setOrderByClause("order_id desc");
        Example.Criteria criteria = example.createCriteria();

        if(status!=null)
            criteria.andEqualTo("status", status);
        if(gtype!=null)
            criteria.andEqualTo("gType", gtype);
        if(StringUtils.isNotBlank(account))
            criteria.andLike("account","%"+account+"%");

        RowBounds rowBounds = RowBoundUtil.getRowBounds(rows, pageSize);
        List<OrderEntity> orderEntities = orderMapper.selectByExampleAndRowBounds(example, rowBounds);
        list.setData(orderEntities);
        int count = orderMapper.selectCountByExample(example);
        list.setTotal(count);
        return list;

//        RowBounds rowBounds=  new RowBounds((pageSize-1)*rows,rows);
//        List<OrderEntity> list = orderMapper.selectByRowBounds(new OrderEntity(),rowBounds);
//        return list;
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public int getOrderCount() {
        List<OrderEntity> list = orderMapper.selectAll();
        return list.size();
    }
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public int getTranCount() {
        return transactionssMapper.selectAll().size();
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public void updateOrderLogistics(Integer orderId, String commp, String commpOrder) {
        OrderEntity orderEntity  = new OrderEntity();
        orderEntity.setOrderId(orderId);
        orderEntity = orderMapper.selectOne(orderEntity);

        if (orderEntity.getStatus().equals(4)){
            throw new ApiException(ErrorCodeEnum.PARAM_200033);
        }
        if (!orderEntity.getStatus().equals(1)){
            throw new ApiException(ErrorCodeEnum.PARAM_200015.code(),ErrorCodeEnum.PARAM_200015.msg());
        }


        orderEntity.setStatus(2);
        orderEntity.setLogisticsCompany(commp);
        orderEntity.setLogisticsNum(commpOrder);
        orderEntity.setModifyDate(new Timestamp(new Date().getTime()));
        orderMapper.updateByPrimaryKey(orderEntity);
    }
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public PageResult<List<TransactionEntity>> getTranList(Integer pageSize, Integer rows) {

        PageResult list=new PageResult();
        Example example=new Example(TransactionEntity.class);
        example.setOrderByClause("id desc");
        Example.Criteria criteria = example.createCriteria();

        RowBounds rowBounds = RowBoundUtil.getRowBounds(rows, pageSize);
        List<TransactionEntity> transactionEntities = transactionssMapper.selectByExampleAndRowBounds(example, rowBounds);
        list.setData(transactionEntities);
        int count = orderMapper.selectCountByExample(example);
        list.setTotal(count);
        return list;
    }

    @Override
    public PageResult<List<TransactionEntity>> getTranListBy(Integer pageSize, Integer rows, String account) {
        PageResult list=new PageResult();
        Example example=new Example(TransactionEntity.class);
        example.setOrderByClause("id desc");
        Example.Criteria criteria = example.createCriteria();
        if(StringUtils.isNotBlank(account))
            criteria.andLike("account","%"+account+"%");

        RowBounds rowBounds = RowBoundUtil.getRowBounds(rows, pageSize);
        List<TransactionEntity> transactionEntities = transactionssMapper.selectByExampleAndRowBounds(example, rowBounds);
        list.setData(transactionEntities);
        int count = orderMapper.selectCountByExample(example);
        list.setTotal(count);
        return list;
    }
}
